<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      http-equiv="X-UA-Compatible"
      content="IE=edge"
    />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <title>Document</title>
    <link
      rel="stylesheet"
      href=""
    />
    <style>
      .continer {
        width: 450px;
        padding: 10px 0 0 10px;
        margin: 100px auto;
        border: 1px solid #000;
      }

      .show {
        height: 100px;
        line-height: 50px;
        margin: 0 10px 20px 0;
        border: 1px solid #000;
        padding-right: 20px;
        text-align: right;
      }

      .box {
        width: 450px;
        height: 310px;
        display: flex;
        text-align: center;
        line-height: 50px;
      }

      .number {
        flex: 3;
        display: flex;
        flex-wrap: wrap;
      }

      .box_item {
        width: 100px;
        height: 50px;
        margin: 0 10px 10px 0;
        border: 1px solid #ccc;
        border-radius: 5px;
        background-image: linear-gradient(
          to left,
          rgba(133, 133, 133, 0.1),
          rgba(212, 212, 212, 0.1)
        );
        box-shadow: 1px 0px 1px 2px rgba(0, 0, 0, 0.1);
      }

      .jisuan {
        flex: 1;
        display: flex;
        flex-wrap: wrap;
      }

      .active {
        box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.1);
      }
    </style>
  </head>
  <body>
    <div class="continer">
      <div class="show">
        <div class="top"></div>
        <div class="bottom"></div>
      </div>

      <div class="box">
        <div class="number">
          <div class="clear_item box_item">CE</div>
          <div class="clear_all_item box_item">C</div>
          <div class="del_item box_item">del</div>
          <div class="num_item box_item">7</div>
          <div class="num_item box_item">8</div>
          <div class="num_item box_item">9</div>
          <div class="num_item box_item">4</div>
          <div class="num_item box_item">5</div>
          <div class="num_item box_item">6</div>
          <div class="num_item box_item">1</div>
          <div class="num_item box_item">2</div>
          <div class="num_item box_item">3</div>
          <div class="float_item box_item">.</div>
          <div class="num_item box_item">0</div>
          <div class="result_item box_item">=</div>
        </div>
        <div class="operator">
          <div class="operator_item box_item">%</div>
          <div class="operator_item box_item">+</div>
          <div class="operator_item box_item">-</div>
          <div class="operator_item box_item">*</div>
          <div class="operator_item box_item">/</div>
        </div>
      </div>
    </div>
    <script>
      // 获取上面的显示容器
      const topShow = document.querySelector('.show .top')
      // 获取下面的显示容器
      const bottomShow = document.querySelector('.show .bottom')
      // 获取清除所有按钮 C
      const clearAllBtn = document.querySelector('.clear_all_item')
      // 获取清除按钮 CE
      const clearBtn = document.querySelector('.clear_item')
      // 获取删除按钮del
      const delBtn = document.querySelector('.del_item')
      // 获取结果按钮 =
      const resultBtn = document.querySelector('.result_item')
      // 获取小数点按钮
      const floatBtn = document.querySelector('.float_item')
      // 获取所有的运算符按钮
      const operatorBtns = document.querySelectorAll('.operator_item')
      // 获取所有的数字按钮
      const numBtns = document.querySelectorAll('.num_item')
      // 定义操作数组
      const operationList = []
      // 定义结果容器
      let result = ''

      // 展示用户输入的函数
      function showTopText() {
        topShow.innerHTML = operationList.join('')
      }

      // 展示结果的函数
      function showBottomText() {
        bottomShow.innerHTML = result
      }

      // 获取操作符索引的函数
      function findOperatorIndex() {
        let operatorIndex = -1
        operatorBtns.forEach((el) => {
          const res = operationList.findIndex((item) => item === el.innerHTML)
          if (res !== -1) {
            operatorIndex = res
          }
        })
        return operatorIndex
      }

      // 获取结果的函数
      function getResult(operatorIndex) {
        // 没有操作符不计算
        if (operatorIndex === -1) return
        // 有操作符没有第二个数字不计算
        if (operatorIndex === operationList.length - 1) return
        // 不能除以0
        if (
          operationList[operationList.length - 2] === '/' &&
          operationList[operationList.length - 1] === '0'
        )
          return

        result = eval(operationList.join(''))
        showBottomText()
      }

      // 重置数组，将结果添加到数组中，清空结果
      function resetOperationList() {
        operationList.length = 0
        operationList.push(result)
        result = ''
      }

      // 添加小数点的逻辑
      function addFloat(array) {
        // 不能让小数点处于开头，小数点前面必须要有数字
        if (!array.length) return
        // 不能在一个数字中出现两个小数点
        let hasFloat = array.some((el) => el === '.')
        if (hasFloat) return
        operationList.push('.')
      }

      // 添加点击反馈
      document.querySelectorAll('.box_item').forEach((el) => {
        el.addEventListener('mousedown', function () {
          this.classList.add('active')
        })
        el.addEventListener('mouseup', function () {
          this.classList.remove('active')
        })
      })

      // 数字按钮按下的逻辑
      numBtns.forEach((el) => {
        el.addEventListener('mouseup', function () {
          operationList.push(this.innerHTML)
          showTopText()
        })
      })

      // 小数点按下的逻辑
      floatBtn.addEventListener('mouseup', function () {
        let operatorIndex = findOperatorIndex()
        let hasFloat
        if (operatorIndex === -1) {
          addFloat(operationList)
        } else {
          let lastNum = operationList.slice(operatorIndex + 1)
          addFloat(lastNum)
        }
        showTopText()
      })

      // 操作符按下的逻辑
      operatorBtns.forEach((el) => {
        el.addEventListener('mouseup', function () {
          if (!operationList.length) return
          let operatorIndex = findOperatorIndex()

          if (operatorIndex !== -1) {
            if (result !== '') {
              resetOperationList()
            } else {
              getResult(operatorIndex)
              resetOperationList()
            }
          }

          operationList.push(this.innerHTML)
          showTopText()
        })
      })

      // 等号按下的逻辑
      resultBtn.addEventListener('mouseup', function () {
        if (!operationList.length) return
        let operatorIndex = findOperatorIndex()
        getResult(operatorIndex)
      })

      // C按下的逻辑
      clearAllBtn.addEventListener('mouseup', function () {
        operationList.length = 0
        result = ''
        showTopText()
        showBottomText()
      })

      // CE按下的逻辑
      clearBtn.addEventListener('mouseup', function () {
        let operatorIndex = findOperatorIndex()
        operationList.length = operatorIndex + 1
        showTopText()
      })

      // del按下的逻辑
      delBtn.addEventListener('mouseup', function () {
        operationList.length -= 1
        showTopText()
      })
    </script>
  </body>
</html>
